#!/usr/bin/env python
#ALL PUZZLES INHERET FROM HERE
import wsgiref.handlers
from pickle import dumps,loads
from google.appengine.api import memcache
import logging
    
def yieldPuzzleInstance(puzzletype):
    data = memcache.get("puzzle")
    if data is not None:
        a = puzzletype()
        a.instanceInfo = loads(data)
        return a
    else:
        a = puzzletype()
        a.instanceInfo = puzzletype.generate()
        memcache.set("puzzle",dumps(a.instanceInfo))
        return a

def burn_library(puzzletype):
    memcache.delete("puzzle")
class abstractPuzzle(object):
    def uniqueName():
        raise Exception("You need to override uniqueName()")
    def nickname():
        raise Exception("You need to override nickname().")
    def generate():
        raise Exception("You need to override generate()")
    uniqueName = staticmethod(uniqueName)
    nickname = staticmethod(nickname)
    generate = staticmethod(generate)

    
    
    
    def solved(self, percentage):
        "Indicate with a value [0-2] what the user should be paid.  0 is no money, 0.5 a 50% solve, 1 is a 100% solve, anything about 1 is for exceptional solutions."
        if percentage < 0 or percentage > 2: raise Exception("Bad percentage")
        logging.info("Solved with %f" % percentage)
        burn_library(self)
        
    
    #OVERRIDE puzzle_get and puzzle_put, not get and put
    def get(self,handler):
        self.puzzle_get(handler)
    def post(self,handler):
        self.puzzle_post(handler)
    def save(self):
        memcache.set("puzzle",dumps(self.instanceInfo))
    def warn_not_logged_in(self):
        return False
def close_enough(floatable,answer,tolerance=0.01):
    "Offsets for rounding errors.  That way if an answer is 'close enough' you can still accept it."
    tolerance *= answer
    if answer >= floatable-tolerance and answer<=floatable+tolerance: return True
    elif answer <= floatable-tolerance and answer>=floatable+tolerance: return True
    else: return False